<template>
  <Btn text="h函数自定义组件" @on-click="fun">
  </Btn>
</template>
<script setup lang="ts">
import { createVNode, render } from 'vue'

// createVNode 函数，参数1 为标签名，参数2 为标签的属性，参数3 为标签的内容，可以为文本也可以为其他的虚拟 DOM
// 该函数返回值为一虚拟 DOM 对象
// createVNode: (string,object,VNode|string)=>VNode

// 对于虚拟 DOM 对象，可以调用 render 渲染器，将其渲染到指定容器内
// render 函数，参数1 为虚拟 DOM 对象，参数2 为容器 HTMLELement 对象
// render:(VNode,HTMLElement)=>{}

// h 函数：实质为 createVNode 函数，即接受 DOM 元素的一系列参数来创建一个虚拟 DOM 元素
// h 函数返回值为一组件对象，可以直接再 html 模板中使用

// 函数式自定义组件：
// 创建一个函数对象，其返回值为一 h 函数的返回值
// 即可以在 html 模板中直接使用该函数对象
// 该函数接受参数为 props 和 ctx
// props 对象用于接受父组件通过自定义属性传递来的值
// ctx 对象用于调用 emit 方法进行自定义事件派发，进行子组件向父组件传值
// ctx 对象用于调用 slots 方法，返回一个插槽的 DOM 对象作为自定义组件父节点的子节点，实现插槽使用
// 函数的返回值为调用 h 函数的返回值

const vnode = createVNode('div', { class: 'box', id: 'div1' }, 'vnode')
render(vnode, document.body)

interface Props {
  text?: string
}
// 自定义组件 Btn
const Btn = (props: Props, ctx: any) => {
  return h(
    'div',
    {
      class: ['leading-6', 'text-white', 'bg-gray-700'],
      onClick: () => {
        console.log('click')
        ctx.emit('on-click', 111)
      },
    },
    props.text,
  )
}
const fun = (val: number) => {
  console.log(val)
}
</script>
<style scoped lang="less"></style>
